package com.iflytek.aiuidemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.example.result.SemanticResultHandler;
import com.example.result.SemanticResultParser;
import com.example.result.entity.SemanticResult;
import com.iflytek.aiui.AIUIErrorCode;
import com.iflytek.aiui.assist.player.AIUIPlayer;
import com.iflytek.aiui.assist.player.AIUIPlayer.AIUIPlayerListener;
import com.iflytek.aiui.assist.player.AIUIPlayer.ContentType;
import com.iflytek.aiui.assist.player.AIUIPlayer.PlayItem;
import com.iflytek.aiui.assist.player.AIUIPlayer.PlayState;
import com.iflytek.aiui.assist.player.AIUIPlayerKitVer;
import com.iflytek.aiui.servicekit.AIUIAgent;
import com.iflytek.aiui.servicekit.AIUIConstant;
import com.iflytek.aiui.servicekit.AIUIEvent;
import com.iflytek.aiui.servicekit.AIUIListener;
import com.iflytek.aiui.servicekit.AIUIMessage;
import com.iflytek.aiui.servicekit.tts.InitListener;
import com.iflytek.aiui.servicekit.tts.SpeechSynthesizer;
import com.iflytek.aiuidemo.constant.DemoConstant;
import com.iflytek.aiuidemo.control.VolumeManager;
import com.iflytek.aiuidemo.player.TonePlayer;
import com.iflytek.aiuidemo.util.DevBoardControlUtil;

/**
 * AIUIDemo为AIUIProductDemo的精简版本，旨在向开发者提供快速简单的AIUI集成示例。
 * 
 * @author <a href="http://www.xfyun.cn">讯飞开放平台</a>
 * @date 2016年8月17日 下午2:56:17 
 *
 */
public class MainActivity extends Activity {
	private final static String TAG = "AIUIDemo";
	
	// 唤醒角度
    private final static String KEY_ANGLE = "angle";
    
	// 唤醒提示音
	private final static String[] WAKE_UP_TONES = {
		DemoConstant.XIAOAI_GREETING_EWZN,
		DemoConstant.XIAOAI_GREETING_GS,
		DemoConstant.XIAOAI_GREETING_SS,
		DemoConstant.XIAOAI_GREETING_WTZN };
	
	private EditText mResultEdit;
	
	// 唤醒状态
	private TextView mStatusText;
	// 音量大小
	private TextView mVolText;
	
	private Button mCreateButton;
	private Button mDestroyButton;
	private Button mStartButton;
	private Button mStopButton;
	private Button mResetButton;
	private Button mResetWakeupButton;
	private Button mStopTTSButton;
	private Button mStopPlayButton;
	private Button mVersionButton;
	
	private Toast mToast;
	
	// 语义结果处理器
	private SemanticResultHandler mResultHandler;
	
	// 音量控制器
	private VolumeManager mVolumeManager;
	
	// 文本合成以及音乐播放器
	private AIUIPlayerKitVer mAIUIPlayer;
	
	// 是否在处理错误标记
	private boolean mIsHandlingError = false;
	
	// 是否已经唤醒标记
	private boolean mIsWakeUp = false;
	
	// AIUI服务代理
	private AIUIAgent mAIUIAgent;

	// AIUI结果监听器
	private AIUIListener mAIUIListener = new AIUIListener() {

		@Override
		public void onEvent(AIUIEvent event) {
			switch (event.eventType) {
				// 绑定成功事件
				case AIUIConstant.EVENT_BIND_SUCESS: 
				{
					// 绑定成功之后服务即为开启状态，无需发送CMD_START命令开启服务
					
					showTip("Service绑定成功");
					
					// 播放绑定成功提示音
					TonePlayer.playTone(MainActivity.this, DemoConstant.BIND_SUCCESS);
				} break;
				
				// 唤醒事件
				case AIUIConstant.EVENT_WAKEUP: 
				{
					// 显示唤醒结果
					mResultEdit.setText(event.info);
					mStatusText.setText("已唤醒");
					
					try {
						// 获得唤醒角度
						JSONObject wakeInfo = new JSONObject(event.info);
						int wakeAngle = wakeInfo.getInt(KEY_ANGLE);
						
						// 设置唤醒角度，打开角度指示灯
						DevBoardControlUtil.setWakeAngle(wakeAngle);
						DevBoardControlUtil.wakeUpLight();
						
						// 停止播放内容
						if (null != mAIUIPlayer) {
							mAIUIPlayer.stop();
						}
						
						mIsHandlingError = false;
						mIsWakeUp = true;
						
						// 随机播放唤醒提示音
						TonePlayer.playTone(MainActivity.this, 
								WAKE_UP_TONES[new Random().nextInt(4)]);
					} catch (JSONException e) {
						e.printStackTrace();
					}
				} break;
	
				// 交互超时触发的休眠事件
				case AIUIConstant.EVENT_SLEEP: 
				{
					// 只处理因交互超时触发的自动休眠
					if (AIUIConstant.TYPE_AUTO == event.arg1) {
						if (null == mAIUIPlayer) {
							return;
						}
						
						if (mAIUIPlayer.getPlayState() == PlayState.MUSIC_PLAYING) {
							DevBoardControlUtil.closeDirectionLight();
							resetWakeup(false);
						} else {
							// 自动休眠
							playGoodByeTheSleep("", false);
						}
					}
				} break;
	
				// 结果事件
				case AIUIConstant.EVENT_RESULT: 
				{
					if (!mIsWakeUp) {
						return;
					}
					
					try {
						// 解析业务结果描述参数，结果格式参见《AIUI集成指南》
						JSONObject bizParamJson = new JSONObject(event.info);
						JSONObject data = bizParamJson.getJSONArray("data").getJSONObject(0);
						JSONObject params = data.getJSONObject("params");
						JSONObject content = data.getJSONArray("content").getJSONObject(0);
	
						if (content.has("cnt_id")) {
							String cnt_id = content.getString("cnt_id");
							String sub = params.optString("sub");
							
							// 从data字段中用cnt_id为key，获取业务结果数据
							JSONObject cntJson = new JSONObject(new String(event.data.getByteArray(cnt_id), "utf-8"));
	
							if ("nlp".equals(sub)) {
								// sub为"nlp"时，表明返回的为语义结果
								JSONObject resultJson = cntJson.getJSONObject("intent");
								
								// 处理语义结果
								handleResult(resultJson);
							} else if ("iat".equals(sub)) {
								// 处理听写结果
							}
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				} break;
	
				// 出错事件
				case AIUIConstant.EVENT_ERROR: 
				{
					int errorCode = event.arg1;
					handleError(errorCode);
					
					mResultEdit.setText("errorCode=" + errorCode);
				} break;
	
				// VAD事件
				case AIUIConstant.EVENT_VAD: 
				{
					if (AIUIConstant.VAD_BOS == event.arg1) {
						showTip("找到vad_bos");
					} else if (AIUIConstant.VAD_EOS == event.arg1) {
						showTip("找到vad_eos");
					} else {
						mVolText.setText("" + event.arg2);
					}
				} break;
				
				default:
					break;
			}
		}

	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 创建合成对象，该对象通过IPC机制调用AIUI Service中的离线合成能力
		SpeechSynthesizer synthesizer = SpeechSynthesizer.createSynthesizer(MainActivity.this, new InitListener() {
			
			@Override
			public void onInit(int code) {
				if (0 == code) {
					// 异步创建合成对象成功，之后方可使用合成能力
				}
			}
		});
		
		// 创建播放器，用于播放音乐和语音合成
		mAIUIPlayer = new AIUIPlayerKitVer(MainActivity.this, synthesizer);
		
		// 初始UI设置
		initUI();
		
		// 注册主动休眠广播接收器
		IntentFilter intentFilter = new IntentFilter(DemoConstant.ACTION_SLEEP);
		registerReceiver(mSleepRecerver, intentFilter);
		
		mResultHandler = SemanticResultHandler.getInstance(MainActivity.this, mAIUIPlayer);
		
		// 获得音量控制对象，并且音量设置为最大
		mVolumeManager = VolumeManager.getInstance(MainActivity.this);
		mVolumeManager.setMaxVolume();
	}
	
	private void initUI() {
		mResultEdit = (EditText) findViewById(R.id.edit_result);
		mStatusText = (TextView) findViewById(R.id.txt_status);
		mVolText = (TextView) findViewById(R.id.txt_vol);
		mCreateButton = (Button) findViewById(R.id.btn_create);
		mDestroyButton = (Button) findViewById(R.id.btn_destroy);
		mStartButton = (Button) findViewById(R.id.btn_start);
		mStopButton = (Button) findViewById(R.id.btn_stop);
		mResetButton = (Button) findViewById(R.id.btn_reset);
		mResetWakeupButton = (Button) findViewById(R.id.btn_resetWakeup);
		mStopTTSButton = (Button) findViewById(R.id.btn_stopTts);
		mStopPlayButton = (Button) findViewById(R.id.btn_stopPlay);
		mVersionButton = (Button) findViewById(R.id.btn_version);

		mToast = Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT);

		mCreateButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (null == mAIUIAgent) {
					// 创建AIUIAgent对象，绑定到AIUIServcie，绑定成功之后服务即为开启状态
					mAIUIAgent = AIUIAgent.createAgent(MainActivity.this, mAIUIListener);
					
					mResultEdit.setText("");
				} else {
					showTip("不要重复绑定");
				}
			}
		});

		mDestroyButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (null != mAIUIAgent) {
					mAIUIAgent.destroy();

					synchronized (MainActivity.this) {
						mAIUIAgent = null;
					}

					mStatusText.setText("未唤醒");

					showTip("AIUIService已解绑");
				} else {
					showTip("Agent为空");
				}
			}
		});

		mStartButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (null != mAIUIAgent) {
					// 发送start消息，开启AIUIService，用于在STOP之后再开启服务
					AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_START,
							0, 0, null, null);
					mAIUIAgent.sendMessage(msg);
					
					mResultEdit.setText("");
					mStatusText.setText("未唤醒");

					showTip("服务已开启");
				} else {
					showTip("Agent为空，请先创建");
				}
			}
		});

		mStopButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (null != mAIUIAgent) {
					// 发送stop消息，停止AIUIService
					AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_STOP, 0,
							0, null, null);
					mAIUIAgent.sendMessage(msg);

					mStatusText.setText("未唤醒");

					showTip("服务已停止");
				} else {
					showTip("Agent为空，请先创建");
				}
			}
		});

		mResetButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (null != mAIUIAgent) {
					// 发送reset消息，重置AIUI Service，相当于stop后再start
					AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_RESET,
							0, 0, null, null);
					mAIUIAgent.sendMessage(msg);
					
					mResultEdit.setText("");
					mStatusText.setText("未唤醒");

					showTip("服务已重置");
				} else {
					showTip("Agent为空，请先创建");
				}
			}
		});

		mResetWakeupButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (null != mAIUIAgent) {
					// 重置AIUI Service的唤醒状态，即重置到未唤醒状态
					AIUIMessage msg = new AIUIMessage(
							AIUIConstant.CMD_RESET_WAKEUP, 0, 0, null, null);
					mAIUIAgent.sendMessage(msg);

					mStatusText.setText("未唤醒");
				} else {
					showTip("Agent为空，请先创建");
				}
			}
		});


		mStopTTSButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (null != mAIUIPlayer) {
					// 停止当前的合成
					mAIUIPlayer.stop(ContentType.TEXT);
				}
			}
		});

		mStopPlayButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (null != mAIUIPlayer) {
					// 停止当前的音乐播放
					mAIUIPlayer.stop(ContentType.MUSIC);
				}
			}
		});
		
		mVersionButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if (null != mAIUIAgent) {
					// 获取AIUI Service的版本号
					String version = mAIUIAgent.getServiceVersion();
					mResultEdit.setText(version);
				} else {
					showTip("Agent为空");
				}
			}
		});
	}

	private void showTip(final String tip) {
		runOnUiThread(new Runnable() {

			@Override
			public void run() {
				if (!TextUtils.isEmpty(tip)) {
					mToast.setText(tip);
					mToast.show();
				}
			}
		});
	}
	
	AIUIPlayerListener mPlayerListener = new AIUIPlayerListener() {

		@Override
		public void onCompleted(PlayItem item, boolean hasNext) {
			
		}

		@Override
		public void onPause(PlayItem arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onProgress(PlayItem item, final int progress) {
			
		}

		@Override
		public void onResume(PlayItem arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onStart(PlayItem arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onStop(PlayItem arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onError(PlayItem arg0, int arg1) {
			// TODO Auto-generated method stub
			
		}
	};
	
	/**
	 * 主动休眠广播监听器。
	 */
	private BroadcastReceiver mSleepRecerver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			// 处理主动休眠（由休眠语义触发）广播
			playGoodByeTheSleep("", false);
		}
		
	};
	
	// 处理语义结果
	private void handleResult(JSONObject jsonResult) {
		SemanticResult semanticResult = SemanticResultParser.parse(jsonResult);
		
		if (null != semanticResult) {
			mResultHandler.handleResult(semanticResult);
		}
	}
	
	/**
	 * 错误处理。注：当出现错误时为了保证较好的交互体验，应播报出错提示语并休眠，结束本次交互（重置唤醒状态）。
	 * 
	 * @param errorCode 错误码
	 */
	private void handleError(int errorCode) {
		// AIUI为持续交互，错误码可能不断快速抛出，为保证只处理一次错误，这里先判断错误处理标记
		if (mIsHandlingError) {
			return;
		}
		
		// 按错误码设置不同的提示文本
		switch (errorCode) {
			case AIUIErrorCode.MSP_ERROR_TIME_OUT:						// 服务器连接超时
			case AIUIErrorCode.ERROR_NO_NETWORK:						// 无网络连接
			case AIUIErrorCode.MSP_ERROR_NO_RESPONSE_DATA: 			// 等待结果超时
			case AIUIErrorCode.MSP_ERROR_LMOD_RUNTIME_EXCEPTION:		// 底层脚本出错								
			case AIUIErrorCode.MSP_ERROR_NOT_FOUND:					// aiui.cfg中scene参数设置出错
			case AIUIErrorCode.ERROR_SERVICE_BINDER_DIED:				// 与AIUIService的绑定断开
		    case AIUIErrorCode.MSP_ERROR_DB_INVALID_APPID:          	// appid校验不通过
			{
				mIsHandlingError = true;
				
				TonePlayer.stopPlay();
				
				String errorTip = "";
				if (AIUIErrorCode.MSP_ERROR_NOT_FOUND == errorCode) {
					errorTip = "场景参数设置出错！";
				} else if (AIUIErrorCode.ERROR_NO_NETWORK == errorCode) {
					errorTip = "网络未连接，请连接网络！";
				} else if (AIUIErrorCode.ERROR_SERVICE_BINDER_DIED == errorCode) {
					errorTip = "AIUI服务已断开！";
				} else if (AIUIErrorCode.MSP_ERROR_DB_INVALID_APPID == errorCode) {
					errorTip = "appid校验不通过!";
				} else {
					// 兜底提示文本
					errorTip = "网络有点问题我去休息了，请稍后再试！";
				} 
				
				// 重置唤醒状态，当出现脚本错误时，需要重置AIUI服务
				playGoodByeTheSleep(errorTip, AIUIErrorCode.MSP_ERROR_LMOD_RUNTIME_EXCEPTION == errorCode);
			} break;
			
		    default:
		    	break;
		}
	}

	/**
	 * 重置为未唤醒状态。
	 * 
	 * @param resetAIUI 是否重置AIUI服务
	 */
	public void resetWakeup(boolean resetAIUI) {
		mStatusText.setText("未唤醒");
		
		// 关闭指示灯
		DevBoardControlUtil.sleepLight();
		
		if (null != mAIUIAgent) {
			if (resetAIUI) {
				// 重置AIUI服务，当服务重置后将处于未唤醒状态
				AIUIMessage resetWakeupMsg = new AIUIMessage(
						AIUIConstant.CMD_RESET, 0, 0, "", null);
				mAIUIAgent.sendMessage(resetWakeupMsg);
			} else {
				// 重置唤醒状态
				AIUIMessage resetWakeupMsg = new AIUIMessage(
						AIUIConstant.CMD_RESET_WAKEUP, 0, 0, "", null);
				mAIUIAgent.sendMessage(resetWakeupMsg);
			}
		}
	}
	
	/**
	 * 播放休眠提示音之后休眠。
	 * 
	 * @param sleepText 休眠提示文本
	 * @param resetAIUI 是否重置AIUI
	 */
	public void playGoodByeTheSleep(String sleepText, final boolean resetAIUI) {
		mIsWakeUp = false;
		
		if (null != mAIUIPlayer) {
			mAIUIPlayer.stop();
		}
		
		// 若休眠文本不为空则合成文本，否则播放休眠提示音
		if (!TextUtils.isEmpty(sleepText)) {
			// 播放休眠文本
			if (null != mAIUIPlayer) {
				PlayItem item = new PlayItem(ContentType.TEXT, sleepText, new Runnable() {
					
					@Override
					public void run() {
						mIsHandlingError = false;
						
						resetWakeup(resetAIUI);
					}
				});
				
				List<PlayItem> itemList = new ArrayList<AIUIPlayer.PlayItem>();
				itemList.add(item);
				
				mAIUIPlayer.playItems(itemList, null);
			}
		} else {
			// 播放休眠提示音
			TonePlayer.playTone(MainActivity.this, DemoConstant.XIAOAI_GOODBYE_NWZL, new Runnable() {
				
				@Override
				public void run() {
					resetWakeup(resetAIUI);
				}
				
			});
		}
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		
		// 销毁AIUI代理
		if (null != mAIUIAgent) {
			mAIUIAgent.destroy();
			
			synchronized (MainActivity.this) {
				mAIUIAgent = null;
			}
		}
		
		unregisterReceiver(mSleepRecerver);
	}
	
}
